#ifndef _WX_PROPGRID_MANAGER_H_
#define _WX_PROPGRID_MANAGER_H_

#include <wx/propgrid/propgrid.h>

#if wxPG_INCLUDE_MANAGER || defined(DOXYGEN)
//#error mmmmmmmmmmm
#include <wx/dcclient.h>
#include <wx/scrolwin.h>
#include <wx/toolbar.h>
#include <wx/stattext.h>
#include <wx/button.h>
#include <wx/textctrl.h>
#include <wx/dialog.h>

extern WXDLLIMPEXP_PG const wxChar *wxPropertyGridManagerNameStr;

class WXDLLIMPEXP_PG wxPropertyGridPage : public wxEvtHandler,
  public wxPropertyGridInterface,
  public wxPropertyGridState {
    friend class wxPropertyGridManager;
    DECLARE_CLASS( wxPropertyGridPage )
  public:
    wxPropertyGridPage();
    virtual ~wxPropertyGridPage();
    virtual void Clear();
    wxSize FitColumns();
    inline int GetIndex() const;
    int GetSplitterPosition( int col = 0 ) const { return GetStatePtr()->DoGetSplitterPosition( col ); }
    wxPGProperty* GetRoot() const { return GetStatePtr()->DoGetRoot(); }
    wxPropertyGridState* GetStatePtr() {
      return this;
    }
    const wxPropertyGridState* GetStatePtr() const { return this; }
    int GetToolId() const { return m_id; }
    virtual void Init() {}
    virtual bool IsHandlingAllEvents() const { return true; }
    virtual void OnShow();
    virtual void RefreshProperty( wxPGProperty* p );
    void SetSplitterPosition( int splitterPos, int col = 0 );
  protected:
    virtual void DoSetSplitterPosition( int pos, int splitterColumn = 0,
                                        bool allPages = false, bool fromAutoCenter = false );
    wxString m_label;
    wxPropertyGridManager*  m_manager;
    int m_id;
  private:
    bool m_isDefault;
  private:
    DECLARE_EVENT_TABLE()
};

class WXDLLIMPEXP_PG wxPropertyGridManager : public wxPanel, public wxPropertyGridInterface {
    DECLARE_CLASS( wxPropertyGridManager )
    friend class wxPropertyGridPage;
  public:
    wxPropertyGridManager();
    wxPropertyGridManager( wxWindow * parent, wxWindowID id = wxID_ANY, const wxPoint & pos = wxDefaultPosition,
                           const wxSize & size = wxDefaultSize, long style = wxPGMAN_DEFAULT_STYLE,
                           const wxString & name = wxPropertyGridManagerNameStr );
    virtual ~wxPropertyGridManager();
    int AddPage( const wxString & label = wxEmptyString, const wxBitmap & bmp = wxPG_NULL_BITMAP,
                 wxPropertyGridPage * pageObj = ( wxPropertyGridPage* ) NULL ) {
      return InsertPage( -1, label, bmp, pageObj );
    }
    bool CanClose() {
      return m_pPropGrid->CanClose();
    }
    void ClearModifiedStatus( wxPGPropArg id );
    void ClearModifiedStatus() { m_pPropGrid->ClearModifiedStatus(); }
    virtual void Clear();
    void ClearPage( int page );
    bool CommitChangesFromEditor( wxUint32 flags = 0 ) { return m_pPropGrid->CommitChangesFromEditor( flags ); }
    bool Create( wxWindow *parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition,
                 const wxSize& size = wxDefaultSize, long style = wxPGMAN_DEFAULT_STYLE,
                 const wxString& name = wxPropertyGridManagerNameStr );
    bool EnableCategories( bool enable ) {
      long fl = m_windowStyle | wxPG_HIDE_CATEGORIES;
      if( enable ) {
        fl = m_windowStyle & ~( wxPG_HIDE_CATEGORIES );
      }
      SetWindowStyleFlag( fl );
      return true;
    }
    bool EnsureVisible( wxPGPropArg id );
    size_t GetChildrenCount() {
      return GetChildrenCount( m_pPropGrid->m_pState->m_properties );
    }
    size_t GetChildrenCount( int pageIndex );
    size_t GetChildrenCount( wxPGPropArg id ) const {
      wxPG_PROP_ARG_CALL_PROLOG_RETVAL( 0 )
      return p->GetChildCount();
    }
    int GetColumnCount( int page = -1 ) const;
    int GetDescBoxHeight() const;
    wxPropertyGrid* GetGrid() {
      wxASSERT( m_pPropGrid );
      return m_pPropGrid;
    };
    const wxPropertyGrid* GetGrid() const {
      wxASSERT( m_pPropGrid );
      return ( const wxPropertyGrid* )m_pPropGrid;
    };
    wxPropertyGridIterator GetIterator( int flags = wxPG_ITERATE_DEFAULT, wxPGProperty* firstProp = NULL ) {
      wxFAIL_MSG( _T( "Please only iterate through individual pages or use CreateVIterator()" ) );
      return wxPropertyGridInterface::GetIterator( flags, firstProp );
    }

    wxPropertyGridConstIterator GetIterator( int flags = wxPG_ITERATE_DEFAULT, wxPGProperty* firstProp = NULL ) const {
      wxFAIL_MSG( _T( "Please only iterate through individual pages or use CreateVIterator()" ) );
      return wxPropertyGridInterface::GetIterator( flags, firstProp );
    }
    wxPropertyGridIterator GetIterator( int flags, int startPos ) {
      wxFAIL_MSG( _T( "Please only iterate through individual pages or use CreateVIterator()" ) );
      return wxPropertyGridInterface::GetIterator( flags, startPos );
    }
    wxPropertyGridConstIterator GetIterator( int flags, int startPos ) const {
      wxFAIL_MSG( _T( "Please only iterate through individual pages or use CreateVIterator()" ) );
      return wxPropertyGridInterface::GetIterator( flags, startPos );
    }
    virtual wxPGVIterator GetVIterator( int flags ) const;
    wxPropertyGridPage* GetCurrentPage() const {
      return GetPage( m_selPage );
    }
    wxPropertyGridPage* GetLastPage() const {
      return GetPage( ( unsigned int )m_arrPages.size() - 1 );
    }
    wxPropertyGridPage* GetPage( unsigned int ind ) const {
      return ( wxPropertyGridPage* )m_arrPages.Item( ind );
    }
    wxPropertyGridPage* GetPage( const wxString& name ) const {
      return GetPage( GetPageByName( name ) );
    }
    int GetPageByName( const wxString& name ) const;
    int GetPageByState( const wxPropertyGridState* pstate ) const;
    virtual wxPropertyGridState* GetPageState( int page ) const;
    size_t GetPageCount() const;
    const wxString& GetPageName( int index ) const;
    wxPGProperty* GetPageRoot( int index ) const;
    wxPGProperty* GetPropertyByLabel( const wxString& name,
                                      wxPropertyGridState** ppState = ( wxPropertyGridState** )NULL ) const;
    wxColour GetPropertyColour( wxPGPropArg id ) const {
      return m_pPropGrid->GetPropertyColour( id );
    }
    wxColour GetPropertyTextColour( wxPGPropArg id ) const {
      return m_pPropGrid->GetPropertyTextColour( id );
    }
    int GetSelectedPage() const { return m_selPage; }
    wxPGProperty* GetSelectedProperty() const {
      return m_pPropGrid->GetSelection();
    }
    int GetSelection() const { return m_selPage; }
    wxToolBar* GetToolBar() const { return m_pToolbar; }
    virtual int InsertPage( int index, const wxString& label, const wxBitmap& bmp = wxNullBitmap,
                            wxPropertyGridPage* pageObj = ( wxPropertyGridPage* ) NULL );
    bool IsAnyModified() const;
    bool IsFrozen() const { return ( m_pPropGrid->m_frozen > 0 ) ? true : false; }
    bool IsPageModified( size_t index ) const;
    virtual bool IsPropertySelected( wxPGPropArg id ) const;
    virtual void Refresh( bool eraseBackground = true, const wxRect* rect = ( const wxRect* ) NULL );
    virtual bool RemovePage( int page );
    void SelectPage( int index );
    void SelectPage( const wxString& label ) {
      int index = GetPageByName( label );
      wxCHECK_RET( index >= 0, _T( "没有具有此名称的页" ) );
      SelectPage( index );
    }
    void SelectPage( wxPropertyGridPage* ptr ) { SelectPage( GetPageByState( ptr ) ); }
    bool SelectProperty( wxPGPropArg id, bool focus = false ) {
      wxPG_PROP_ARG_CALL_PROLOG_RETVAL( false )
      return p->GetParentState()->DoSelectProperty( p, focus );
    }
    void SetColumnCount( int colCount, int page = -1 );
    void SetDescription( const wxString& label, const wxString& content );
    void SetCaptionTextColour( wxPGPropArg id, const wxColour& col ) {
      m_pPropGrid->SetCaptionTextColour( id, col );
    }
    void SetDescBoxHeight( int ht, bool refresh = true );
    void SetPropertyAttributeAll( const wxString& name, wxVariant value );
    void SetPropertyBackgroundColour( wxPGPropArg id, const wxColour& col ) {
      m_pPropGrid->SetPropertyBackgroundColour( id, col );
    }
    void SetPropertyTextColour( wxPGPropArg id, const wxColour& col ) {
      m_pPropGrid->SetPropertyTextColour( id, col );
    }
    void SetPropertyColourToDefault( wxPGPropArg id ) {
      m_pPropGrid->SetPropertyColourToDefault( id );
    }
    void SetSplitterLeft( bool subProps = false, bool allPages = true );
    void SetPageSplitterPosition( int page, int pos, int column = 0 ) {
      GetPage( page )->DoSetSplitterPosition( pos, column );
    }
    void SetSplitterPosition( int pos, int column = 0 );
    void SetStringSelection( const wxChar* name ) {
      SelectPage( GetPageByName( name ) );
    }
    bool ClearSelection() { return m_pPropGrid->ClearSelection(); }
  protected:
    virtual wxPropertyGrid * CreatePropertyGrid() const;
    virtual void RefreshProperty( wxPGProperty * p );
  public:
    virtual wxSize DoGetBestSize() const;
    void SetId( wxWindowID winid );
    virtual void Freeze();
    virtual void Thaw();
    virtual void SetExtraStyle( long exStyle );
    virtual bool SetFont( const wxFont & font );
    virtual void SetWindowStyleFlag( long style );
    virtual bool Reparent( wxWindowBase * newParent );
  protected:
  public:
    void OnMouseMove( wxMouseEvent & event );
    void OnMouseClick( wxMouseEvent & event );
    void OnMouseUp( wxMouseEvent & event );
    void OnMouseEntry( wxMouseEvent & event );
    void OnPaint( wxPaintEvent & event );
    void OnToolbarClick( wxCommandEvent & event );
    void OnResize( wxSizeEvent & event );
    void OnPropertyGridSelect( wxPropertyGridEvent & event );
  protected:
    wxPropertyGrid * m_pPropGrid;
    wxArrayPtrVoid  m_arrPages;
    wxToolBar * m_pToolbar;
    wxStaticText * m_pTxtHelpCaption;
    wxStaticText * m_pTxtHelpContent;
    wxPropertyGridPage * m_emptyPage;
    long m_iFlags;
    int m_selPage;
    int m_width;
    int m_height;
    int m_extraHeight;
    int m_splitterY;
    int m_splitterHeight;
    int m_nextTbInd;
    int m_dragOffset;
    wxCursor m_cursorSizeNS;
    int m_nextDescBoxSize;
    wxWindowID m_baseId;
    unsigned char m_dragStatus;
    unsigned char m_onSplitter;
    virtual wxPGProperty * DoGetPropertyByName( wxPGPropNameStr name ) const;
    virtual bool DoSelectPage( int index );
    void Init1();
    void Init2( int style );
    void RecalculatePositions( int width, int height );
    void RecreateControls();
    void UpdateDescriptionBox( int new_splittery, int new_width, int new_height );
    void RepaintSplitter( wxDC & dc, int new_splittery, int new_width, int new_height, bool desc_too );
    void SetDescribedProperty( wxPGProperty * p );
    virtual bool SetEditableStateItem( const wxString & name, wxVariant value );
    virtual wxVariant GetEditableStateItem( const wxString & name ) const;
    virtual bool ProcessEvent( wxEvent & event );
  private:
    DECLARE_EVENT_TABLE()
};

inline int wxPropertyGridPage::GetIndex() const {
  if( !m_manager ) {
    return wxNOT_FOUND;
  }
  return m_manager->GetPageByState( this );
}

#endif
#endif
